package com.lib.net;

import android.os.Handler;
import android.os.Looper;

import androidx.annotation.NonNull;

import com.lib.net.util.LogUtils;
import com.lib.net.util.OnLoadingListener;

import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.Response;

/**
 * Created by Joey on 2018/3/22.
 */
public abstract class NetResponseListener implements Callback, OnUploadListener {

    protected Handler mainHandler = new Handler(Looper.getMainLooper());

    protected OnLoadingListener onLoadingListener;

    protected ResponseError error;

    private boolean debug = false;
    protected String method;

    public NetResponseListener setDebug(boolean debug) {
        this.debug = debug;
        return this;
    }

    public boolean isDebug() {
        return debug || NetClientConfig.I.isDebug();
    }

    public void setMethod(String method) {
        this.method = method;
    }

    /**
     * http 头部
     */
    private Map<String, String> header;

    public void onStart() {
        if (onLoadingListener != null) {
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    onLoadingListener.show();
                }
            });
        }
    }

    public void setOnLoadingListener(OnLoadingListener listener) {
        this.onLoadingListener = listener;
    }

    public abstract void onSuccess(Call call, final Response response);

    public abstract void onError(Call call, ResponseError error);

    public abstract void onError(ResponseError error) throws Exception;

    public void headers(Map<String, String> header) {

    }

    @Override
    public void onFailure(final Call call, final IOException e) {
        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                if (onLoadingListener != null) {
                    onLoadingListener.dismiss();
                }
            }
        });
        LogUtils.i("");
        e.printStackTrace();
        String msg = e.getMessage();
        ResponseError error = new ResponseError(ResponseError.ERRPR_BY_SERVER, msg);
        if (e instanceof SocketTimeoutException) {
            error = new ResponseError(ResponseError.ERRPR_NO_RESPONCE, msg);
            onError(call, error);
        } else if (e instanceof ConnectException) {
            error = new ResponseError(ResponseError.ERRPR_NETWORK_UNREACHABLE, msg);
            onError(call, error);
        } else if (e instanceof SocketException) {
//            LogUtils.e("连接被主动成功取消！");
            onError(call, error);
        } else {
            onError(call, error);
        }

    }

    @Override
    public void onResponse(final Call call, final Response response) throws IOException {
        LogUtils.i("");
        getHeader(response.headers());
        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                if (onLoadingListener != null) {
                    onLoadingListener.dismiss();
                }
                headers(header);
            }
        });
        if (!response.isSuccessful()) {
            onError(call, new ResponseError(response.code() + "", "", response.body().string()));
            throw new IOException("Unexpected code " + response);
        }

        onSuccess(call, response);
    }

    @NonNull
    private Map<String, String> getHeader(Headers headers) {
        header = new HashMap<>();
        for (String name : headers.names()) {
            header.put(name, headers.get(name));
        }
        return header;
    }


}
